package com.cnhis.cloudhealth.clinical.clidoctor.commons.utils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class Map2Bean {
	
	/** 
     * 将一个 JavaBean 对象转化为一个  Map 
     * @param bean 要转化的JavaBean 对象 
     * @return 转化出来的  Map 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */   
    @SuppressWarnings({ "rawtypes", "unchecked" })   
    public static Map convertBean(Object bean)   
            throws IntrospectionException, IllegalAccessException, InvocationTargetException {   
        Class type = bean.getClass();   
        Map returnMap = new HashMap();   
        BeanInfo beanInfo = Introspector.getBeanInfo(type);   
   
        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();   
        for (int i = 0; i< propertyDescriptors.length; i++) {   
            PropertyDescriptor descriptor = propertyDescriptors[i];   
            String propertyName = descriptor.getName();   
            if (!propertyName.equals("class")) {   
                Method readMethod = descriptor.getReadMethod();   
                Object result = readMethod.invoke(bean, new Object[0]);   
                if (result != null) {   
                    returnMap.put(propertyName, result);   
                } else {   
                    returnMap.put(propertyName, "");   
                }   
            }   
        }   
        return returnMap;   
    }
    
    
    
    /** 
     * 将一个 Map 对象转化为一个 JavaBean 
     * @param type 要转化的类型 
     * @param map 包含属性值的 map 
     * @return 转化出来的 JavaBean 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InstantiationException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */   
    @SuppressWarnings("rawtypes")   
    public static Object convertMap(Class type, Map map)   
            throws IntrospectionException, IllegalAccessException,   
            InstantiationException, InvocationTargetException {   
        BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性 
        Object object=type.newInstance();
    
        // 给 JavaBean 对象的属性赋值   
        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();   
        for (int i = 0; i< propertyDescriptors.length; i++) {   
            PropertyDescriptor descriptor = propertyDescriptors[i];   
            String propertyName = descriptor.getName();   
            
            if (map.containsKey(propertyName)) {   
                // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。   
            	 Class propertyType = descriptor.getPropertyType(); 
                Object value = null;
				try {
					value = decode(propertyType, (String)map.get(propertyName));
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
                Object[] args = new Object[1]; 
               
                args[0] =value;   
               
                descriptor.getWriteMethod().invoke(object, args);   
            }   
        }   
        return object;   
    }   
    /**
	 * 把相应的字段转换成和数据库相同的数据类型
	 * @param type 需要转换的实体
	 * @param value每个字段的值
	 * @return 和数据库相匹配的字段的值
	 * @throws Exception
	 */
	private static Object decode(Class type, String value) throws Exception { 
        if (type.getName().equals("java.lang.String")) { 
            return value; 
        } 
        if (type.getName().equals("java.lang.Boolean")) { 
            return Boolean.valueOf(value); 
        } 
        if (type.getName().equals("java.lang.Integer")) { 
            return Integer.valueOf(value); 
        } 
        if (type.getName().equals("java.lang.Long")) { 
            return Long.valueOf(value); 
        } 
        if (type.getName().equals("java.lang.Float")) { 
            return Float.valueOf(value); 
        } 
        if (type.getName().equals("java.lang.Double")) { 
            return Double.valueOf(value); 
        } 
        if (type.getName().equals("java.lang.Class")) { 
            return Class.forName(value); 
        } 
        return null; 
    } 

}
